/**
 * 
 */
package com.dalonedrow.module.hq.rpg;

import com.dalonedrow.engine.sprite.base.SpriteImageObjectFactory;
import com.dalonedrow.engine.systems.JOGLErrorHandler;
import com.dalonedrow.pooled.PooledStringBuilder;
import com.dalonedrow.pooled.StringBuilderPool;

/**
 * Represents an auto-tile cell. Auto-tile cells are defined by their terrain
 * types and corners. There are a total of 16 combinations of corners, and their
 * values define which side has the major/minor terrain types displayed in each
 * corner.
 * @author Donald
 */
public final class UltimaTileCell implements Comparable {
	/**
	 * the value of the cell's sides.<br>
	 * cells are laid out in the following pattern:<br>
	 * <br>
	 * &nbsp;&nbsp;&nbsp;&nbsp;<u>b0</u><br>
	 * b3|<u>&nbsp;&nbsp;</u>|b1<br>
	 * &nbsp;&nbsp;&nbsp;&nbsp;b2<br>
	 */
	private int	cornerFlags;
	/** the cell's sprite reference id. */
	private int	imageRefId;
	/** the type of terrain the cell represents. */
	private int	type;
	/** the cell's x-position. */
	private int	x;
	/** the cell's y-position. */
	private int	y;
	/**
	 * Creates a new instance of {@link UltimaTileCell}.
	 * @param newX the cell's x-position
	 * @param newY the cell's y-position
	 * @param newType the tile type associate with this cell
	 * @param flags the corner values to set
	 */
	public UltimaTileCell(final int newX, final int newY, final int newType,
			final int flags) {
		x = newX;
		y = newY;
		type = newType;
		cornerFlags = flags;
		setImageRefId();
	}
	/**
	 * Determines if side b0 contains the cell's major terrain.
	 * @return true if the top side contains the cell's major terrain; false
	 *         otherwise
	 */
	public boolean b0CornerHasMajorTerrain() {
		return (cornerFlags & 1) == 1;
	}
	/**
	 * Determines if side b1 contains the cell's major terrain.
	 * @return true if the right side contains the cell's major terrain; false
	 *         otherwise
	 */
	public boolean b1CornerHasMajorTerrain() {
		return (cornerFlags & 2) == 2;
	}
	/**
	 * Determines if side b2 contains the cell's major terrain.
	 * @return true if the bottom side contains the cell's major terrain; false
	 *         otherwise
	 */
	public boolean b2CornerHasMajorTerrain() {
		final int four = 4;
		return (cornerFlags & four) == four;
	}
	/**
	 * Determines if side b3 contains the cell's major terrain.
	 * @return true if the left side contains the cell's major terrain; false
	 *         otherwise
	 */
	public boolean b3CornerHasMajorTerrain() {
		final int eight = 8;
		return (cornerFlags & eight) == eight;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public int compareTo(final Object o) {
		int val = -1;
		if (o instanceof UltimaTileCell) {
			if (y < ((UltimaTileCell) o).y) {
				val = -1;
			} else if (y > ((UltimaTileCell) o).y) {
				val = 1;
			} else {
				if (x < ((UltimaTileCell) o).x) {
					val = -1;
				} else if (x > ((UltimaTileCell) o).x) {
					val = 1;
				} else {
					val = 0;
				}
			}
		}
		return val;
	}
	/**
	 * Gets the value of the cell's corners.
	 * @return <code>int</code>
	 */
	public int getCornerFlags() {
		return cornerFlags;
	}
	/**
	 * Gets the cell's sprite reference id.
	 * @return <code>int</code>
	 */
	public int getImageRefId() {
		return imageRefId;
	}
	/**
	 * Gets the cell's type.
	 * @return <code>int</code>
	 */
	public int getType() {
		return type;
	}
	/**
	 * Gets the cell's x-position.
	 * @return int
	 */
	public int getX() {
		return x;
	}
	/**
	 * Gets the cell's y-position.
	 * @return int
	 */
	public int getY() {
		return y;
	}
	/** Sets the top-left corner to contain the cell's major terrain. */
	public void setb0CornerMajor() {
		cornerFlags |= 1;
		setImageRefId();
	}
	/** Sets the top-left corner to contain the cell's minor terrain. */
	public void setb0CornerMinor() {
		cornerFlags &= ~1;
		setImageRefId();
	}
	/** Sets the top-right corner to contain the cell's major terrain. */
	public void setb1CornerMajor() {
		cornerFlags |= 2;
		setImageRefId();
	}
	/** Sets the top-right corner to contain the cell's minor terrain. */
	public void setb1CornerMinor() {
		cornerFlags &= ~2;
		setImageRefId();
	}
	/** Sets the bottom-left corner to contain the cell's major terrain. */
	public void setb2CornerMajor() {
		final int four = 4;
		cornerFlags |= four;
		setImageRefId();
	}
	/** Sets the bottom-left corner to contain the cell's minor terrain. */
	public void setb2CornerMinor() {
		final int four = 4;
		cornerFlags &= ~four;
		setImageRefId();
	}
	/** Sets the bottom-right corner to contain the cell's major terrain. */
	public void setb3CornerMajor() {
		final int eight = 8;
		cornerFlags |= eight;
		setImageRefId();
	}
	/** Sets the bottom-right corner to contain the cell's minor terrain. */
	public void setb3CornerMinor() {
		final int eight = 8;
		cornerFlags &= ~eight;
		setImageRefId();
	}
	/**
	 * Sets the value of the cell's corners.
	 * @param flags the corner values to set
	 */
	public void setCornerFlags(final int flags) {
		cornerFlags = flags;
		setImageRefId();
	}
	/** Sets the cell's sprite reference id. */
	private void setImageRefId() {
		PooledStringBuilder sb =
				StringBuilderPool.getInstance().getStringBuilder();
		try {
			sb.append(HQTerrainTypes.getInstance().getTerrainName(type));
			sb.append("_");
			sb.append(cornerFlags);
			imageRefId = SpriteImageObjectFactory.getInstance().getImageRefId(
					sb.toString());
		} catch (Exception ex) {
			JOGLErrorHandler.getInstance().fatalError(ex);
		} finally {
			sb.returnToPool();
		}
	}
	/**
	 * Sets the cell's sprite reference id.
	 * @param id the id to set
	 */
	public void setImageRefId(final int id) {
		imageRefId = id;
	}
	/**
	 * Sets the cell's tile type.
	 * @param newType the tile type associate with this cell
	 */
	public void setType(final int newType) {
		type = newType;
		setImageRefId();
	}
	/**
	 * Sets the cell's x-position.
	 * @param newX the cell's x-position
	 */
	public void setX(final int newX) {
		x = newX;
	}
	/**
	 * Sets the cell's y-position.
	 * @param newY the cell's y-position
	 */
	public void setY(final int newY) {
		y = newY;
	}
}
